#pragma once
#include "evdeploy/core/ev_common_data.h"
#include "model_handle.h"
#include "version_config.h"
#include <dlfcn.h>
#include <fstream>
#include <iostream>
#include <mutex>
namespace ev
{
#define CREATE_INFER_INS(ENGINE)                                                                                       \
    extern "C" void *create_infer_ins() { return new ENGINE; }
#define DESTROY_INFER_INS(ENGINE)                                                                                      \
    extern "C" void destroy_infer_ins(void *ins)                                                                       \
    {                                                                                                                  \
        ENGINE *t_ins = (ENGINE *)ins;                                                                                 \
        delete t_ins;                                                                                                  \
    }

#define CHECK_LYNXI_API(express)                                                                                           \
    {                                                                                                                  \
        int lynxi_ret = express;                                                                                       \
        if (lynxi_ret != 0)                                                                                            \
        {                                                                                                              \
            EVLOG(ERROR) << "lynxi api call error, ret=" << lynxi_ret << " " << __FILE__ << " " << __LINE__;           \
            exit(-1);                                                                                                  \
        }                                                                                                              \
    }

    class EVBaseLynxiModel
    {
      public:
        EVBaseLynxiModel() {}

        virtual ~EVBaseLynxiModel() { ; }

        // load model and initization
        virtual EVStatus Init(const char *net, void **config) = 0;

        // relsease source
        virtual EVStatus UnInit() = 0;

        // run optimize, like tensorrt optimize
        virtual EVStatus OptimizeModel(const char *model_name) = 0;

        // run inference
        virtual EVStatus Infer(EVModelData *in, EVModelData *out) = 0;

        virtual EVStatus SetIO(const std::vector<std::string> &inputs, const std::vector<std::string> &outputs) = 0;

      protected:
        bool m_init_flag = false;
    };

    class EVLynxiModel
    {
      public:
        EVLynxiModel();

        virtual ~EVLynxiModel();

      protected:
        int m_dev_id{0};
        bool m_is_ok{false};
        lynModel_t m_lynxi_model;
        ev::LynxiModelHandle m_linxi_handle;

      protected:
        /**
         * @brief load onnx format model for ov
         * @param[in] str_model_name: onnx model file name
         * @return
         */
        void LoadLynxiModel(const std::string str_model_name);
    };

} // namespace ev